/** @file caGenerator.h
 * ConArtist supports a number of generators, each of which can manage
 * content for any number of sites or sections of a site.
 */

/*
 * Licensed to the ConArtist Development Team (CADT).
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 * The CADT licenses this file to you under the Apache License, 
 * Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef CAGENERATOR_H
#define CAGENERATOR_H

#include <apr_pools.h>
#include <apr_tables.h>
#include <apr_thread_rwlock.h>
#include <apr_hash.h>

#include "caPipeline.h"

struct caDir;

/** @defgroup GENERATOR ConArtist Site Generators
 * @{
 */

/** Each defined site generator is represented by a caGenerator structure.
 * This contains all information neccesary to create content and map
 * URL's to content.
 */
struct caGenerator {
    apr_pool_t *pool;            /**< pool to use for memory allocations */
    apr_table_t *cfg;            /**< configurtaion for this generator */
    char *name;                  /**< Internal name */

    struct caMapStore *mapStore; /**< Pointer to map store */
    
    apr_thread_rwlock_t *storeLock; /**< RW lock for store operations */
    apr_hash_t *storeHash;       /**< Hash of named stores */
    apr_hash_t *piHash;          /**< Hash array of pipelines */
};

/** @defgroup CAM_ ConArtist URI Map Constants
 * @ingroup GENERATOR
 * @{
 */

#define CAM_CACHE       0x0001   /**< Cache output */
#define CAM_CLEAN       0x0002   /**< Output file is clean */
#define CAM_DIRTY       0x0004   /**< Ouptut needs to be regenerated */

/** @} */

/** @fn apr_status_t caGeneratorCreate(struct caGenerator **genr, 
                                       const char *name)
 * Create a content generator object.
 * @param genr Pointer to the created caGenerator structure
 * @param name The internal name to assign this generator
 */
apr_status_t caGeneratorCreate(struct caGenerator **, const char *);

/** @fn apr_status_t caGeneratorAddStore(struct caGenerator *gen,
                                         const char *name,
                                         const char *storeName)
 * Add a store to a generator. The store will be added with the
 * name supplied.
 * @note The name supplied is internal to the generator it is added
 *       to.
 * @param gen The caGenerator object to add the store to
 * @param name The internal name to assign. If this is NULL then the
 *             storeName will be used.
 * @param storeName Name of the store to add
 * @note Stores have a global name that is used throughout Conartist to
 *       reference the strore, but within each generator they can have a 
 *       name assigned when added using this function.
 */
apr_status_t caGeneratorAddStore(struct caGenerator *, const char *,
                                 const char *);

/** @fn apr_status_t caRegisterHostname(struct caGenerator *gen, 
                                        const char *host, apr_port_t port)
 * Register a hostname. This function creates a link between the supplied
 * hostname and content generator.
 * Once registered all requests for the supplied hostname will be
 * processed by the supplied content generator.
 * @param gen Pointer to a caGenerator object
 * @param host Hostname to be handled
 * @param port The port number on the host to register
 */
apr_status_t caRegisterHostname(struct caGenerator *, const char *, 
                                apr_port_t);

/** @fn apr_status_t caGeneratorFind(struct caGenerator **gen,
                                     const char *hostname, apr_port_t port, 
                                     const char *URL)
 * Search for the content generator object that handles the supplied
 * hostname.
 * @param gen Pointer to the caGenerator structure found
 * @param hostname The hostnanme to search for (including port).
 * @param port The port number to search for
 * @param URL The path portion of the URL
 * @returns Returns a pointer to a caGenerator object or NULL if none found.
 */
apr_status_t caGeneratorFind(struct caGenerator **, const char *, 
                             apr_port_t, const char *);

/** @fn apr_status_t caGeneratorGetFilename(char **filename,
                                            const char *path, 
                                            struct caGenerator *gen)
 * Get a full filename from a path within the generator. The path can
 * specify the store to use by prefixing it to the path in the form
 * STORE:PATH.
 * @param filename Pointer to the full filename
 * @param path The partial path in the generator/store to return a full
 *             filename for.
 * @param gen Pointer to the generator structure to find the path within
 */
apr_status_t caGeneratorGetFilename(char **, const char *, 
                                    struct caGenerator *);

/** @fn apr_status_t caGeneratorAddPipeline(struct caGenerator *gen, 
                                            struct caPipeline *pipeline);
 * Add a pipeline to the generator specified.
 * @param gen The generator to add the pipeline to.
 * @param pipeline The pipeline structure to add
 */
apr_status_t caGeneratorAddPipeline(struct caGenerator *, 
                                    struct caPipeline *);

/** @fn apr_status_t caGeneratorFindPipeline(struct pipelineInstance **pipe,
                                             const char *name,
                                             struct caGenerator *gen)
 * @param pipe Pointer to the pipeline instance structure found
 * @param name Name of the pipeline to find
 * @param gen The generator to search
 */
apr_status_t caGeneratorFindPipeline(struct pipelineInstance **,
                                     const char *,
                                     struct caGenerator *);

/** @fn apr_status_t caGeneratorOpenDir(struct caDir **thedir,
                                const char *path, 
                                struct caGenerator *gen)
 * Open a directory from a generator. This should be used as it
 * respects store settings.
 * @param thedir Returned pointer to a caDir structure
 * @param path The path to open, can include store.
 * @param gen pointer to the generator structure to open dir for
 */
apr_status_t caGeneratorOpenDir(struct caDir **, const char *, 
                                struct caGenerator *);

/** @} */

#endif /* CAGENERATOR_H */
